﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.IO;
using System.Web;

namespace CoyoEden.Web
{
	/// <summary>
	/// A ViewManager which allows you to render a usercontrol and return the generated HTML
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <remarks>
	/// http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx
	/// </remarks>
	public class ViewManager<T> where T : Control
	{

		#region Properties

		private T _control = default(T);

		/// <summary>
		/// Gives you access to the control you are rendering allows
		/// you to set custom properties etc.
		/// </summary>
		public T Control {
			get {
				return _control;
			}
		}

		// Used as a placeholder page to render the control on.
		private System.Web.UI.Page _holder = null;
		/// <summary>
		/// whether the view depends on a existing page instance
		/// </summary>
		private bool _hasDependingPage;

		#endregion

		#region Constructor

		/// <summary>
		/// Default constructor for this view manager, pass in the path for the control
		/// that this view manager is render.
		/// </summary>
		/// <param name="inPath"></param>
		public ViewManager(string inPath) {
			//Init the holder page
			_holder = new System.Web.UI.Page();

			// Create an instance of our control
			_control = (T)_holder.LoadControl(inPath);

			// Add it to our holder page.
			_holder.Controls.Add(_control);
		}
		/// <summary>
		/// Renderring a view which depends on a page instance.If u construct a viewmanager with this constructor,the view to be render won't raise any of its event handlers,such as "Page_Load","On_PreInit"...
		/// </summary>
		/// <param name="dependingPage">view's depending page</param>
		/// <param name="viewPath">view's virtual path</param>
		public ViewManager(string viewPath,Page dependingPage) {
			_holder = dependingPage;
			_control = (T)_holder.LoadControl(viewPath);
			_hasDependingPage = true;
		}
		#endregion

		#region Rendering

		/// <summary>
		/// Renders the current control.
		/// </summary>
		/// <returns></returns>
		public string Render() {
			using (StringWriter sw = new StringWriter())
			{
				if (!_hasDependingPage)
				{
					// Execute the page capturing the output in the stringwriter.
					HttpContext.Current.Server.Execute(_holder, sw, false);
				}
				else {
					_control.RenderControl(new HtmlTextWriter(sw));
				}
				// Return the output.
				return sw.ToString();
			}
		}
		#endregion

	}
}
